李守中

PVE 宿主机相关

Table of Contents

1. ZFS 相关

1.1. ZFS 参数如何自定义

所有的 ZFS 参数都在 /sys/module/zfs/parameters 目录中,可以用 cat 命令查看,或使用 echo 修改参数。

要让 Linux 在开机时加载用户自定义的 ZFS 参数,需要将参数以如下格式写入 /etc/modprobe.d/zfs.conf 中:

options zfs PARAMETER=VALUE

1.2. 常用的优化参数

以下内容写入到 /etc/modprobe.d/zfs.conf 中:

  • options zfs l2arc_rebuild_enabled=1 (如果使用了 L2ARC 的话) PVE 使用的 OpenZFS 会在每次开机后丢弃 L2ARC 设备中的所有数据。这个设置可以让操作系统在开机后根据 L2ARC 设备中的已有数据重新建立索引,不丢弃 L2ARC 设备中已有的数据。这个参数在 FreeBSD 中默认开启,在 PVE 上默认关闭。

1.3. zpool 的 [email protected] 执行失败 no such pool available

ZFS 安装时创建的 zpool 名为 rpool ,它不是引起问题的原因,而且,通常它不会出现导入失败的问题。

PVE 中负责导入 zpool 的 systemd service 有两个:

  1. /lib/systemd/system/zfs-import-cache.service
    • ExecStart=/sbin/zpool import -c /etc/zfs/zpool.cache -aN $ZPOOL_IMPORT_OPTS=
    • /etc/zfs/zpool.cache 存储了 zpool 的配置的缓存
      • zpool set cachefile=<path> <zpool-name> 可设置 zpool 的配置的缓存的位置, <path>'' (空串) 表示使用默认位置,为 none 表示该 zpool 永远不会为配置创建缓存
      • zpool 的配置的缓存可以让操作系统在启动时发现所有的 zpool。系统引导时会自动导入此文件中记录定的所有 zpool
      • 多个 zpool 可共享同一个文件。在添加或移除 zpool 时,内核会销毁并重新创建此文件,并自动添加或移除对应 zpool 的配置的缓存信息,因此在试图访问此文件时应小心
      • 在导出或销毁最后一个使用 cachefile 的 zpool 后,该文件被删除
  2. /lib/systemd/system/[email protected]
    • ExecStart=/sbin/zpool import -N -d /dev/disk/by-id -o cachefile=none %I
    • systemctl enable zfs-import@<zpool-name>.service 可以使指定的池在开机时被自动导入

然而,每当用户在 WebUI 上创建了新的 zpool:

  1. 该 zpool 会被立即导入
  2. PVE 会自动生成 zfs-import@<zpool-name>.service 并设置开机执行

而 WebUI 并没有在创建新 zpool 时提供 cachefile 的配置接口,所以新的 zpool 会使用 cachefile 的默认值,即,/etc/zfs/zpool.cache。这就意味着,此时,新的 zpool 的配置的缓存也被放在了 /etc/zfs/zpool.cache 文件中。

所以,被用户在 WebUI 上创建的新的 zpool 如果不在关机前导出 (删除 /etc/zfs/zpool.cache 中新 zpool 的配置的缓存信息) 的话,那么下次开机时新的 zpool 会被导入两次,一次是 zfs-imoprt-cache.service,另一次是 zfs-import@<zpool-name>.service。

还要注意到,存放了 rootfs 的 rpool 并没有类似于 [email protected] 的文件,所以 rpool 是被 zfs-import-cache.service 导入的,所以它会先于 [email protected] 被执行,而 zfs-import-cache.service 被执行时会根据 /etc/zfs/zpool.cache 文件导入 zpool。

这就导致如果新的 zpool 的配置的缓存还在 /etc/zfs/zpool.cache 文件中的话,那它会随 rpool 的导入而被导入,然后 zfs-imoprt@<zpool-name>.service 无法导入一个已经被导入的 zpool 就会执行失败。

no such pool available 的错误就出现了。

知道原因之后要解决也很简单:

  • 如果新 zpool 不会被经常导入导出,并且希望在开机时导入这个新的 zpool:
    • systemctl disable zfs-import@<zpool-name>.service 让新的 zpool 不被独立地导入
    • 而由于新的 zpool 已经导入过一次了,所以它的配置的缓存也存在于 /etc/zfs/zpool.cache 文件中,可以被 zfs-import-cache.service 导入
  • 如果新 zpool 经常被导入导出,并且希望在开机时导入这个新的 zpool:
    • zpool set cachefile=none <zpool-name> 先让新的 zpool 的配置不被写入 /etc/zfs/zpool.cache
    • 手动导出新的 zpool 一次,以删除已经存在于 /etc/zfs/zpool.cache 中的信息
    • systemctl enable zfs-import@<zpool-name>.service 为新的 zpool 创建一个独立的 service 并使其在开机时被执行
    • systemctl restart zfs-import@<zpool-name>.service 手动执行这个独立的 service 以测试新的 zpool 是否能被正常导入

2. 宿主机系统

2.1. 换源

将 /etc/apt/sources.list 内容改为如下所示:

deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-updates main contrib non-free
deb http://mirrors.tuna.tsinghua.edu.cn/debian-security buster/updates main contrib non-free

注意: 不能把 deb http://mirrors.tuna.tsinghua.edu.cn/debian/ buster-backports main contrib non-free 也给添加进去,这可能导系统更新时 PVE 定制的包被开源包替换掉。

/etc/apt/sources.list.d/pve-enterprise.list 内容为 PVE 核心包的更新源。但因为没有买订阅,所以这个源不可用。

在不买订阅的情况下可以用 PVE 免费的软件源,但是根据官方文档,这个源里的包只适用于测试或非生产环境。

所以直接把 /etc/apt/sources.list.d/pve-enterprise.list 注释掉,不从网络更新 PVE 核心包。

2.2. 从 ISO 升级系统

2.2.1. 常规流程

首先从 PVE 官网下载最新的 ISO 文件,上传到服务器中。

打开 SSH 连接,命令类似如下:

mkdir /mnt/pve-iso
mount proxmox-ve_7.3-1.iso /mnt/pve-iso
echo 'deb [trusted=yes] file:///mnt/pve-iso/ bullseye pve' > /etc/apt/sources.list.d/local-iso.list

命令中:

  1. mount proxmox-ve_7.3-1.iso /mnt/iso 中的 proxmox-ve_7.3-1.iso 替换为 ISO 文件的名称。
  2. 找到 PVE 当前大版本号对应的 Debian 系统,将 deb [trusted=yes] file:///mnt/iso/ buster pve 中的 buster 替换为 Debian 系统代号。

最后 apt update && apt upgrade

如果最后输出有 The following packages have been kept back 则需要检查输出中提到的包被升级后会不会有兼容问题。如果确认可以升级,执行 apt dist-upgrade

2.2.2. pve-firmware : Conflicts: firmware-linux-free but <date>.<version> is to be installed

这个问题一般出现在从 linux 安装的 PVE 上面,从官方 ISO 安装的系统不会有这个问题。

出现 pve-firmware 冲突的话,只需要卸载 linux-image-amd64 就可以正常升级了。

最后可以清理一下不被依赖的包。

root@j4105:~# apt upgrade -y
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
Calculating upgrade... Done
Some packages could not be installed. This may mean that you have
requested an impossible situation or if you are using the unstable
distribution that some required packages have not yet been created
or been moved out of Incoming.
The following information may help to resolve the situation:

The following packages have unmet dependencies:
 pve-firmware : Conflicts: firmware-linux-free but 20200122-1 is to be installed
E: Broken packages

root@j4105:~# apt remove --purge linux-image-amd64
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
The following packages will be REMOVED:
  linux-image-amd64
0 upgraded, 0 newly installed, 1 to remove and 116 not upgraded.
After this operation, 13.3 kB disk space will be freed.
Do you want to continue? [Y/n] y
(Reading database ... 51751 files and directories currently installed.)
Removing linux-image-amd64 (5.10.70-1) ...

root@j4105:~# apt autoremove --purge -y

2.3. 删除系统分配的 local-lvm

  1. 备份虚拟机;
  2. 删除虚拟机;
  3. lvremove pve/data 删除 local-lvm 逻辑卷;
  4. lvextend -l +100%FREE -r pve/root 把原 local-lvm 空间分配给 local;
  5. 删除 local-lvm: 数据中心 -> 存储 -> 删除 local-lvm;
  6. 编辑 local,内容里添加 磁盘映像容器
  7. 恢复虚拟机。

注意,xfs 文件系统有个特点是 不支持缩小文件系统 ,这意味着文件系统扩容后再用 lvextend 缩小文件系统会导致文件系统损坏,即使恢复成功也会丢一些文件。

2.4. 重命名一个宿主机

PVE 只推荐给全新安装的机器重命名,不推荐给已经有虚拟机的或者加入集群的宿主机重命名。

给一个全新安装的机器重命名只需要改以下文件就够了:

  • /etc/hosts
  • /etc/hostname
  • /etc/mailname
  • /etc/postfix/main.cf

而如果这台机器虽然没加入集群,但是已经用了一段时间了 (指上面有虚拟机、容器和备份任务之类用到了主机名的地方),在改完上面的地方之后,打开 WebUI 上虚拟机详情页则会看到类似于下面内容的报错:

hostname lookup '<hostname>' failed – failed to get address info for: <hostname>: Name or service not known (500)

对于无法启动的虚拟机和容器:

  1. 备份旧的节点配置: cp -r /etc/pve/nodes/<old-hostname> ~
  2. 用新的主机名创建新的节点配置: mkdir /etc/pve/nodes/<new-hostname>
    1. 先把能复制的东西都复制到新目录下: cp -r /etc/pve/nodes/<old-hostname> /etc/pve/nodes/<new-hostname>
    2. 不能用 cp 或者 mv 批量复制或移动虚拟机或容器的配置文件。这两个操作都会报错:
      • cp: cannot create regular file '/etc/pve/nodes/<new-hostname>/qemu-server/<vmid>.conf': File exists
      • mv: cannot move '/etc/pve/nodes/<old-hostname>/qemu-server' to '/etc/pve/nodes/<new-hostname>/qemu-server': Directory not empty
    3. 只能一个一个地移动虚拟机或者容器的配置文件 mv /etc/pve/nodes/<old-hostname>/qemu-server/<vmid>.conf /etc/pve/nodes/<new-hostname>/qemu-server
  3. 删除旧的节点配置: rm -rf /etc/pve/nodes/<old-hostname>

对于备份等任务,编辑 /etc/pve/jobs.cfg 文件中 node 字段对应的主机名即可。也可以在 WebUI -> Datacenter -> Backup -> 双击备份任务修改主机名。

关于上述第二步只能一个一个复制虚拟机或者容器配置文件的原因,和这篇文档 https://pve.proxmox.com/wiki/Proxmox_Cluster_File_System_(pmxcfs) 所描述的 Proxmox Cluster file system (pmxcfs) 有关。文档的最后一节提到只能用 mv 命令来转移虚拟机配置文件。只能通过 mv 命令来移动虚拟机和容器配置文件的限制应该是受这个文件系统的影响,但是目前找不到 PVE 官方更详细的关于 pmxcfs 的文档。

3. 宿主机网络

3.1. 端口组配置

主要是配置 Bond 和 Bridge 网络接口。

在主机的网络选项卡中创建一个 Linux Bond 网卡,配置信息可以参考下面一段配置文件。

auto lo
iface lo inet loopback

iface eno1 inet manual

iface enp4s0 inet manual

auto bond0
iface bond0 inet manual
        bond-slaves eno1 enp4s0
        bond-miimon 100
        bond-mode active-backup
        bond-primary eno1

auto vmbr0
iface vmbr0 inet dhcp
        bridge-ports bond0
        bridge-stp off
        bridge-fd 0

3.2. 宿主机从 DHCP 获取 IP

/etc/network/interfaces 文件里面有类似如下内容:

auto lo
iface lo inet loopback

iface eno1 inet manual

iface enp4s0 inet manual

# 网卡 enp4s0 在网桥 vmbr0 中
# 手动获取 IP
auto vmbr0
iface vmbr0 inet manual
        address 192.168.1.10
        netmask 255.255.255.0
        gateway 192.168.1.3
        bridge-ports enp4s0
        bridge-stp off
        bridge-fd 0

要让 vmbr0 采用 DHCP 的方式从上级路由器获取 IP,可以采用如下写法:

auto lo
iface lo inet loopback

iface eno1 inet manual

iface enp4s0 inet manual

# 网卡 enp4s0 在网桥 vmbr0 中
# 从 DHCP 服务器获取 IP
auto vmbr0
iface vmbr0 inet dhcp
        bridge-ports enp4s0
        bridge-stp off
        bridge-fd 0

重启之后,可在上级路由器处查到 PVE 宿主机的 IP 地址。

注意: 在 WebUI 上配置好网络后,生成的配置文件是 /etc/network/interfaces.new。机器重启后,旧的 /etc/network/interfaces 被删除,/etc/network/interfaces.new 被重命名为 /etc/network/interfaces,然后 PVE 使用这个新的 /etc/network/interfaces 来配置网络。

4. 其他问题与解决方案

4.1. 上传 ISO 文件卡住

PVE 会在 /var/tmp 创建 buffer 以缓存上传来的文件,待上传并校验之后再转存去其他地方。

所以根目录下剩余空间大小应大于要上传文件的大小才能上传成功。

如果 PVE 的安装盘过小,比如用了 16G 的傲腾固态或者像安装 ESXi 那样把系统装在 USB 设备上 (比如 SD 卡配读卡器或者 U 盘),可能出现缓存区空间不足的情况。

具体表现就是上传的进度条会卡住,如果切到 local 存储的 概要 选项卡会看到 使用率 进度条前后乱跳。

4.2. 删除在 Web 控制台上创建的 Directory

(如果使用 ZFS 作为 PVE 的文件系统则不会出现 Directory 的 systemd.mount service)

PVE 所有存储相关的配置都在 /etc/pve/storages.cfg 里完成。

从 WebUI 创建 Directory 后,配置信息被记入 /etc/pve/storages.cfg,对应的硬盘由 systemd.mount 负责挂载。

从 WebUI 删除 Directory 时,只有 /etc/pve/storages.cfg 中的配置被删除了,被创建在 /etc/systemd/system 中的由 systemd.mount 负责的挂载任务还在,需要手动删除。

比如,一个挂载任务的内容像下面这样的 cat /etc/systemd/system/mnt-pve-testxfs.mount:

[Install]
WantedBy=multi-user.target

[Mount]
Options=defaults
Type=xfs
What=/dev/disk/by-uuid/5a0a6149-ce8f-4e36-94c4-348d0d133e72
Where=/mnt/pve/testxfs

[Unit]
Description=Mount storage 'testxfs' under /mnt/pve


Last Update: 2023-09-27 Wed 16:16

Generated by: Emacs 28.2 (Org mode 9.5.5)   Contact: [email protected]

若正文中无特殊说明,本站内容遵循: 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议